package com.fan.tools.csvUtils;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;

import com.alibaba.fastjson.util.IOUtils;
import com.fan.base.exception.BusinessException;
import com.fan.base.utils.DateUtils;
import com.fan.base.Constants;

public class CsvUtils {

	/**
	 * @param csvList
	 * @return
	 */
	public static <T> String createCsvFile(List<T> csvList) {
		StringBuilder sBuilder = new StringBuilder();
		if (CollectionUtils.isEmpty(csvList)) {
			return sBuilder.toString();
		}
		// 获取类中所有字段信息
		Field[] fields = csvList.get(0).getClass().getDeclaredFields();
		if (fields.length <= 0) {
			return sBuilder.toString();
		}

		/*
		 * 获取有哪些需要导出的字段ֵ
		 */
		Map<Integer, String> csvMap = new TreeMap<Integer, String>();
		for (Field field : fields) {
			CsvFiled csvAnnotation = field.getAnnotation(CsvFiled.class);
			if (csvAnnotation != null) {
				csvMap.put(csvAnnotation.cellNum(), field.getName());
			}
		}
		/*
		 *导出字段赋值
		 */
		for (Object csvField : csvList) {
			for (Map.Entry<Integer, String> fieldName : csvMap.entrySet()) {
				sBuilder.append(getvalue(csvField, fieldName.getValue())).append(Constants.COMMA_EN);
			}
			// 拼接换行字符串
			sBuilder.replace(sBuilder.length() - 1, sBuilder.length(), Constants.NEW_LINE);
		}
		return sBuilder.toString();
	}

	private static String getvalue(Object csvField, String fieldName) {
		String returnString = Constants.EMPTY_STR;
		try {
			Field field = csvField.getClass().getDeclaredField(fieldName);
			field.setAccessible(true);
			Object value = field.get(csvField);
			if (value == null) {
				returnString = "";
			} else if (value instanceof Date) {
				CsvFiled csvAnnotation = field.getAnnotation(CsvFiled.class);
				returnString = DateUtils.toString((Date) value, csvAnnotation.DateFormat());
			} else if (value instanceof BigDecimal) {
				returnString = ((BigDecimal) value).toString() + Constants.TABS;
			} else {
				returnString = String.valueOf(value);
				//如果是数字类型，拼接间隔符，防止科学计数法
				if (NumberUtils.isDigits(returnString)) {
					returnString = returnString + Constants.TABS;
				}
				//防止有换行特殊字符，导致错行错列
				if (StringUtils.isNotBlank(returnString)) {
					returnString = returnString.replaceAll(Constants.REPLICE_NEWLINE, "").replaceAll(Constants.QUOTE_STR, "\\")
							.replaceAll(Constants.COMMA_EN, "，");
		        } 
			}
		} catch (NoSuchFieldException | SecurityException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		return returnString;
	}

	public static String createCsvHeader(Class<?> classNmae) {
		Field[] fields = classNmae.getDeclaredFields();
		// 非空判断
		if (fields.length <= 0) {
			throw new BusinessException("没有要导出的字段信息");
		}
		Map<Integer, String> cellMap = new TreeMap<Integer, String>();
		if (fields.length > 0) {
			for (Field field : fields) {
				CsvFiled csvField = field.getAnnotation(CsvFiled.class);
				if (csvField != null) {
					if (csvField.cellNum() < 0) {
						throw new BusinessException(field.getName() + "的CsvField注解的属性cellNum不能小于0!");
					}
					if (StringUtils.isBlank(csvField.cellName())) {
						throw new BusinessException(field.getName() + "的CsvField注解的属性cellName不能为空!");
					}
					if (StringUtils.isNoneBlank(cellMap.get(csvField.cellNum()))) {
						throw new BusinessException(field.getName() + "的CsvField的 cellNum属性不能为空!");
					}
					cellMap.put(csvField.cellNum(), csvField.cellName());
				}
			}
		}

		return StringUtils.join(cellMap.values(), Constants.COMMA_EN) + Constants.NEW_LINE;
	}
	
	
	/**
	 * 创建csv文件
	 * @param fileName
	 * @param content
	 * @return
	 */
	public static String createCsvFile(String fileName, List<?> csvList) {
		
		StringBuffer stringBuffer = new StringBuffer();
		stringBuffer.append(CsvUtils.createCsvHeader(csvList.get(0).getClass()));
		stringBuffer.append(CsvUtils.createCsvFile(csvList));
		File file = new File(fileName);
		Writer writer = null;
		try {
			writer = new FileWriter(file);
			writer.write(stringBuffer.toString());
			writer.flush();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			IOUtils.close(writer);
		}
		
		return file.getPath();
		
	}
}
